"""
接口自动化相关Pydantic模式
"""

from typing import List, Optional, Dict, Any, Union
from pydantic import BaseModel, Field, validator
from datetime import datetime


# API接口相关模式
class ApiParameterBase(BaseModel):
    name: str = Field(..., max_length=100)
    description: Optional[str] = None
    param_type: str = Field(..., pattern="^(header|query|body|path)$")
    data_type: str = Field(default="string", pattern="^(string|integer|boolean|array|object|number)$")
    is_required: bool = False
    default_value: Optional[str] = None
    example_value: Optional[str] = None
    validation_rules: Optional[Dict[str, Any]] = None
    source_type: str = Field(default="static", pattern="^(static|variable|response|env)$")
    source_config: Optional[Dict[str, Any]] = None


class ApiParameterCreate(ApiParameterBase):
    pass


class ApiParameterUpdate(BaseModel):
    name: Optional[str] = Field(None, max_length=100)
    description: Optional[str] = None
    param_type: Optional[str] = Field(None, pattern="^(header|query|body|path)$")
    data_type: Optional[str] = Field(None, pattern="^(string|integer|boolean|array|object|number)$")
    is_required: Optional[bool] = None
    default_value: Optional[str] = None
    example_value: Optional[str] = None
    validation_rules: Optional[Dict[str, Any]] = None
    source_type: Optional[str] = Field(None, pattern="^(static|variable|response|env)$")
    source_config: Optional[Dict[str, Any]] = None


class ApiParameter(ApiParameterBase):
    id: int
    interface_id: int

    class Config:
        from_attributes = True


class ApiAssertionBase(BaseModel):
    name: str = Field(..., max_length=200)
    description: Optional[str] = None
    assertion_type: str = Field(..., max_length=50)
    target_path: Optional[str] = Field(None, max_length=500)
    operator: str = Field(..., max_length=20)
    expected_value: Optional[str] = None
    is_enabled: bool = True


class ApiAssertionCreate(ApiAssertionBase):
    pass


class ApiAssertionUpdate(BaseModel):
    name: Optional[str] = Field(None, max_length=200)
    description: Optional[str] = None
    assertion_type: Optional[str] = Field(None, max_length=50)
    target_path: Optional[str] = Field(None, max_length=500)
    operator: Optional[str] = Field(None, max_length=20)
    expected_value: Optional[str] = None
    is_enabled: Optional[bool] = None


class ApiAssertion(ApiAssertionBase):
    id: int
    interface_id: int

    class Config:
        from_attributes = True


class ApiInterfaceBase(BaseModel):
    name: str = Field(..., max_length=200)
    description: Optional[str] = None
    method: str = Field(..., pattern="^(GET|POST|PUT|DELETE|PATCH|HEAD|OPTIONS)$")
    url: str = Field(..., max_length=500)
    headers: Optional[Dict[str, str]] = None
    query_params: Optional[Dict[str, Any]] = None
    body_type: str = Field(default="json", pattern="^(json|form|raw|xml|none)$")
    body_content: Optional[str] = None
    auth_type: Optional[str] = Field(None, pattern="^(none|basic|bearer|api_key|oauth2)$")
    auth_config: Optional[Dict[str, Any]] = None
    status: str = Field(default="active", pattern="^(active|inactive|deprecated)$")
    category: Optional[str] = Field(None, max_length=100)
    tags: Optional[List[str]] = None


class ApiInterfaceCreate(ApiInterfaceBase):
    parameters: Optional[List[ApiParameterCreate]] = []
    assertions: Optional[List[ApiAssertionCreate]] = []


class ApiInterfaceUpdate(BaseModel):
    name: Optional[str] = Field(None, max_length=200)
    description: Optional[str] = None
    method: Optional[str] = Field(None, pattern="^(GET|POST|PUT|DELETE|PATCH|HEAD|OPTIONS)$")
    url: Optional[str] = Field(None, max_length=500)
    headers: Optional[Dict[str, str]] = None
    query_params: Optional[Dict[str, Any]] = None
    body_type: Optional[str] = Field(None, pattern="^(json|form|raw|xml|none)$")
    body_content: Optional[str] = None
    auth_type: Optional[str] = Field(None, pattern="^(none|basic|bearer|api_key|oauth2)$")
    auth_config: Optional[Dict[str, Any]] = None
    status: Optional[str] = Field(None, pattern="^(active|inactive|deprecated)$")
    category: Optional[str] = Field(None, max_length=100)
    tags: Optional[List[str]] = None


class ApiInterface(ApiInterfaceBase):
    id: int
    created_by: Optional[int] = None
    created_at: datetime
    updated_at: Optional[datetime] = None
    parameters: List[ApiParameter] = []
    assertions: List[ApiAssertion] = []

    class Config:
        from_attributes = True


# 场景相关模式 - 步骤相关schemas已删除，使用流程图替代
class TestScenarioBase(BaseModel):
    name: str = Field(..., max_length=200)
    description: Optional[str] = None
    status: str = Field(default="draft", pattern="^(draft|ready|running|completed|failed)$")
    timeout: int = Field(default=30, ge=1, le=3600)
    retry_count: int = Field(default=0, ge=0, le=5)
    parallel_execution: bool = False
    environment_variables: Optional[Dict[str, str]] = None


class TestScenarioCreate(TestScenarioBase):
    pass  # 步骤通过流程图管理


class TestScenarioUpdate(BaseModel):
    name: Optional[str] = Field(None, max_length=200)
    description: Optional[str] = None
    status: Optional[str] = Field(None, pattern="^(draft|ready|running|completed|failed)$")
    timeout: Optional[int] = Field(None, ge=1, le=3600)
    retry_count: Optional[int] = Field(None, ge=0, le=5)
    parallel_execution: Optional[bool] = None
    environment_variables: Optional[Dict[str, str]] = None
    # 步骤通过流程图管理


class TestScenario(TestScenarioBase):
    id: int
    created_by: Optional[int] = None
    created_at: datetime
    updated_at: Optional[datetime] = None
    # 步骤通过流程图管理

    class Config:
        from_attributes = True


# 执行相关模式
class StepExecutionResultBase(BaseModel):
    step_name: str = Field(..., max_length=200)
    step_order: int
    status: str = Field(..., pattern="^(passed|failed|skipped|error)$")
    request_url: Optional[str] = None
    request_method: Optional[str] = None
    request_headers: Optional[Dict[str, str]] = None
    request_body: Optional[str] = None
    response_status_code: Optional[int] = None
    response_headers: Optional[Dict[str, str]] = None
    response_body: Optional[str] = None
    response_time: Optional[float] = None
    assertion_results: Optional[List[Dict[str, Any]]] = None
    extracted_variables: Optional[Dict[str, Any]] = None
    error_message: Optional[str] = None
    error_details: Optional[str] = None


class StepExecutionResult(StepExecutionResultBase):
    id: int
    execution_id: int
    executed_at: datetime

    class Config:
        from_attributes = True


class ScenarioExecutionBase(BaseModel):
    execution_id: str = Field(..., max_length=50)
    status: str = Field(..., pattern="^(pending|running|completed|failed|cancelled)$")
    total_steps: int = 0
    passed_steps: int = 0
    failed_steps: int = 0
    skipped_steps: int = 0
    start_time: Optional[datetime] = None
    end_time: Optional[datetime] = None
    duration: Optional[float] = None
    result_summary: Optional[str] = None
    error_message: Optional[str] = None
    execution_log: Optional[str] = None


class ScenarioExecution(ScenarioExecutionBase):
    id: int
    scenario_id: int
    executor_id: Optional[int] = None
    created_at: datetime
    step_results: List[StepExecutionResult] = []

    class Config:
        from_attributes = True


# 环境配置相关模式
class EnvironmentConfigBase(BaseModel):
    name: str = Field(..., max_length=100)
    description: Optional[str] = None
    base_url: Optional[str] = Field(None, max_length=500)
    variables: Optional[Dict[str, str]] = None
    headers: Optional[Dict[str, str]] = None
    is_default: bool = False
    is_active: bool = True


class EnvironmentConfigCreate(EnvironmentConfigBase):
    pass


class EnvironmentConfigUpdate(BaseModel):
    name: Optional[str] = Field(None, max_length=100)
    description: Optional[str] = None
    base_url: Optional[str] = Field(None, max_length=500)
    variables: Optional[Dict[str, str]] = None
    headers: Optional[Dict[str, str]] = None
    is_default: Optional[bool] = None
    is_active: Optional[bool] = None


class EnvironmentConfig(EnvironmentConfigBase):
    id: int
    created_by: Optional[int] = None
    created_at: datetime
    updated_at: Optional[datetime] = None

    class Config:
        from_attributes = True


# 调试和执行相关模式
class ApiTestRequest(BaseModel):
    """单个接口测试请求"""
    interface_id: int
    environment_id: Optional[int] = None
    parameter_overrides: Optional[Dict[str, Any]] = None
    variables: Optional[Dict[str, str]] = None


class ApiTestResponse(BaseModel):
    """单个接口测试响应"""
    success: bool
    status_code: Optional[int] = None
    response_time: Optional[float] = None
    response_headers: Optional[Dict[str, str]] = None
    response_body: Optional[str] = None
    assertion_results: Optional[List[Dict[str, Any]]] = None
    error_message: Optional[str] = None


class ScenarioExecuteRequest(BaseModel):
    """场景执行请求"""
    scenario_id: int
    environment_id: Optional[int] = None
    variables: Optional[Dict[str, str]] = None
    debug_mode: bool = False


class ScenarioExecuteResponse(BaseModel):
    """场景执行响应"""
    execution_id: str
    status: str
    message: str


class ScenarioDebugRequest(BaseModel):
    """场景调试请求"""
    scenario_id: int
    step_id: Optional[int] = None  # 如果指定，只执行到该步骤
    environment_id: Optional[int] = None
    variables: Optional[Dict[str, str]] = None


# 列表查询相关模式
class PaginationParams(BaseModel):
    page: int = Field(default=1, ge=1)
    size: int = Field(default=20, ge=1, le=100)


class ApiInterfaceListParams(PaginationParams):
    search: Optional[str] = None
    category: Optional[str] = None
    status: Optional[str] = None
    method: Optional[str] = None


class TestScenarioListParams(PaginationParams):
    search: Optional[str] = None
    status: Optional[str] = None
    created_by: Optional[int] = None


class ScenarioExecutionListParams(PaginationParams):
    scenario_id: Optional[int] = None
    status: Optional[str] = None
    executor_id: Optional[int] = None
    start_date: Optional[datetime] = None
    end_date: Optional[datetime] = None


# 响应模式
class PaginatedResponse(BaseModel):
    items: List[Any]
    total: int
    page: int
    size: int
    pages: int


class ApiInterfaceListResponse(BaseModel):
    items: List[ApiInterface]
    total: int
    page: int
    size: int
    pages: int


class TestScenarioListResponse(BaseModel):
    items: List[TestScenario]
    total: int
    page: int
    size: int
    pages: int


class ScenarioExecutionListResponse(BaseModel):
    items: List[ScenarioExecution]
    total: int
    page: int
    size: int
    pages: int


# ==================== 流程图相关 ====================

class FlowNodeCreate(BaseModel):
    """创建流程节点的请求模型"""
    node_id: str = Field(..., max_length=50, description="前端生成的节点ID，如 'start_1', 'api_2'")
    name: str = Field(..., max_length=200, description="节点名称")
    description: Optional[str] = Field(None, description="节点描述")
    node_type: str = Field(..., max_length=20, description="节点类型：start, end, api, condition, loop")
    position_x: float = Field(0, description="节点在画布上的X坐标")
    position_y: float = Field(0, description="节点在画布上的Y坐标")
    node_config: Optional[Dict[str, Any]] = Field(None, description="节点配置信息，如接口参数、条件逻辑等")
    is_enabled: bool = Field(True, description="是否启用该节点")
    continue_on_failure: bool = Field(False, description="失败时是否继续执行")
    interface_id: Optional[int] = Field(None, description="关联的接口ID（仅API节点使用）")


class FlowNodeUpdate(BaseModel):
    """更新流程节点的请求模型"""
    name: Optional[str] = Field(None, max_length=200, description="节点名称")
    description: Optional[str] = Field(None, description="节点描述")
    position_x: Optional[float] = Field(None, description="节点在画布上的X坐标")
    position_y: Optional[float] = Field(None, description="节点在画布上的Y坐标")
    node_config: Optional[Dict[str, Any]] = Field(None, description="节点配置信息")
    is_enabled: Optional[bool] = Field(None, description="是否启用该节点")
    continue_on_failure: Optional[bool] = Field(None, description="失败时是否继续执行")
    interface_id: Optional[int] = Field(None, description="关联的接口ID（仅API节点使用）")


class FlowNode(BaseModel):
    """流程节点的响应模型（数据库模型对应）"""
    id: int = Field(..., description="数据库主键ID")
    node_id: str = Field(..., description="前端节点ID")
    name: str = Field(..., description="节点名称")
    description: Optional[str] = Field(None, description="节点描述")
    node_type: str = Field(..., description="节点类型")
    position_x: float = Field(..., description="X坐标")
    position_y: float = Field(..., description="Y坐标")
    node_config: Optional[Dict[str, Any]] = Field(None, description="节点配置")
    is_enabled: bool = Field(..., description="是否启用")
    continue_on_failure: bool = Field(..., description="失败时是否继续")
    scenario_id: int = Field(..., description="所属场景ID")
    interface_id: Optional[int] = Field(None, description="关联接口ID")
    created_at: datetime = Field(..., description="创建时间")
    updated_at: Optional[datetime] = Field(None, description="更新时间")

    class Config:
        from_attributes = True


class FlowConnectionCreate(BaseModel):
    """创建流程连接的请求模型"""
    connection_id: str = Field(..., max_length=50, description="前端生成的连接ID，如 'edge_1'")
    name: Optional[str] = Field(None, max_length=200, description="连接名称")
    source_node_id: str = Field(..., description="源节点ID（前端字符串格式）")
    target_node_id: str = Field(..., description="目标节点ID（前端字符串格式）")
    condition_config: Optional[Dict[str, Any]] = Field(None, description="条件配置，用于条件分支")
    connection_type: str = Field(default="default", max_length=20, description="连接类型：default, condition")
    is_enabled: bool = Field(True, description="是否启用该连接")


class FlowConnectionUpdate(BaseModel):
    """更新流程连接的请求模型"""
    name: Optional[str] = Field(None, max_length=200, description="连接名称")
    condition_config: Optional[Dict[str, Any]] = Field(None, description="条件配置")
    connection_type: Optional[str] = Field(None, max_length=20, description="连接类型")
    is_enabled: Optional[bool] = Field(None, description="是否启用")


class FlowConnection(BaseModel):
    """流程连接的内部模型（数据库模型对应，使用整数节点ID）"""
    id: int = Field(..., description="数据库主键ID")
    connection_id: str = Field(..., description="前端连接ID")
    name: Optional[str] = Field(None, description="连接名称")
    source_node_id: int = Field(..., description="源节点数据库ID")
    target_node_id: int = Field(..., description="目标节点数据库ID")
    condition_config: Optional[Dict[str, Any]] = Field(None, description="条件配置")
    connection_type: str = Field(..., description="连接类型")
    is_enabled: bool = Field(..., description="是否启用")
    scenario_id: int = Field(..., description="所属场景ID")
    created_at: datetime = Field(..., description="创建时间")
    updated_at: Optional[datetime] = Field(None, description="更新时间")

    class Config:
        from_attributes = True


class ScenarioFlowData(BaseModel):
    """场景流程数据的请求模型，用于保存流程图"""
    nodes: List[FlowNodeCreate] = Field(..., description="流程节点列表")
    connections: List[FlowConnectionCreate] = Field(..., description="流程连接列表")


class FlowConnectionResponse(BaseModel):
    """流程连接的API响应模型（使用前端字符串节点ID）
    
    与FlowConnection的区别：
    - FlowConnection：内部使用，节点ID为数据库整数ID
    - FlowConnectionResponse：API响应使用，节点ID为前端字符串ID
    这样设计是为了解决前端Vue Flow需要字符串ID匹配节点的问题
    """
    id: int = Field(..., description="数据库主键ID")
    connection_id: str = Field(..., description="前端连接ID")
    name: Optional[str] = Field(None, description="连接名称")
    source_node_id: str = Field(..., description="源节点前端ID（字符串格式）")
    target_node_id: str = Field(..., description="目标节点前端ID（字符串格式）")
    condition_config: Optional[Dict[str, Any]] = Field(None, description="条件配置")
    connection_type: str = Field(..., description="连接类型")
    is_enabled: bool = Field(..., description="是否启用")
    scenario_id: int = Field(..., description="所属场景ID")
    created_at: datetime = Field(..., description="创建时间")
    updated_at: Optional[datetime] = Field(None, description="更新时间")


class ScenarioFlowResponse(BaseModel):
    """场景流程图的API响应模型"""
    nodes: List[FlowNode] = Field(..., description="流程节点列表")
    connections: List[FlowConnectionResponse] = Field(..., description="流程连接列表（使用前端字符串节点ID）")